#include"Mystring.h"
#include<iostream>
#include<cstring>
#include<cstdlib>

Mystring::Mystring():size(0),capacity(15)
{
    // std::cout<<"无参构造"<<std::endl;
    string= new char[capacity];
}

Mystring::Mystring(const char *str)
{
    // std::cout<<"有参构造"<<std::endl;
    size=strlen(str);
    capacity=size+1;
    string= new char[capacity];
    strcpy(string,str);
}

Mystring::Mystring(const Mystring &s):size(s.size),capacity(s.capacity)
{
    // std::cout<<"拷贝构造函数"<<std::endl;
    string= new char[capacity];
    strcpy(string, s.string);
}

Mystring &Mystring::operator=(const Mystring &s)
{
    delete []string;
    size=s.size;
    capacity=s.capacity;
    string= new char[capacity];
    strcpy(string, s.string);
    return *this;  //左值拷贝会造成拷贝构造，所以要用引用，避免拷贝构造
}

Mystring &Mystring::operator+=(const Mystring &s)
{
    size+=s.size;
    if(size+1>capacity)
    {
        capacity= size+1;
        char *newS=new char[capacity];
        memset(newS,0,capacity);
        strcpy(newS,string);
        delete []string;
        string= newS;
    }
    strcat(string,s.string);
    return *this;
}

Mystring &Mystring::operator+=(const char &c)
{
    if(size+1>=capacity)
    {
        capacity*=2;
        char *newS=new char[capacity];
        memset(newS,0,capacity);
        strcpy(newS,string);
        delete []string;
        string= newS;
    }
    string[size++]=c;
    string[size]='\0';
    return *this;
}

Mystring Mystring::operator+(const Mystring &s)
{
    Mystring result= *this;
    result+= s;
    return result;
}

Mystring &Mystring::operator-=(const Mystring &s)
{
    char* dest=strstr(this->string,s.string);
    while(dest)
    {
        char *back=dest+s.size;
        while(*back!='\0')
        {
            *dest=*back;
            dest++;
            back++;
        }
        *dest='\0';
        dest=strstr(this->string,s.string);
    }
    return *this;
}

Mystring Mystring::operator-(const Mystring &s)
{
    Mystring result= *this;
    result-= s;
    return result;
}

char &Mystring::operator[](int index)
{
    return string[index];
}

bool Mystring::operator==(const Mystring &s)
{
    return strcmp(string,s.string)==0;
}

Mystring::operator int()
{
    return atoi(string);
}

Mystring::operator double()
{
    return atof(string);
}

MystringArray Mystring::split(const Mystring &delim)
{
    Mystring temp= *this;
    MystringArray result;
    char *dest= strtok(temp.string,delim.string);
    while(dest)
    {
        result+= dest;
        dest= strtok(nullptr, delim.string);
    }
    return result;
}

std::ostream& operator<<(std::ostream& os, const Mystring& s)
{
    std::cout<<s.string;
    return os;
}

std::istream &operator>>(std::istream &is, Mystring &s)
{
    s.clear();
    char c=0;
    while(c=getchar()!='\n')
    {
        s+=c;
    }
    return is;
}

void Mystring::clear()
{
    memset(string,0,capacity);
    size=0;
}

Mystring::~Mystring()
{
    delete []string;
}

// MystringArray
MystringArray::MystringArray():size(0),capacity(15)
{
    array= new Mystring[capacity];
}

MystringArray::MystringArray(const MystringArray &str):size(str.size),capacity(str.capacity)
{
    array= new Mystring[capacity];
    for(int i=0; i<size; i++)
    {
        array[i]=str.array[i];
    }
}

MystringArray& MystringArray::operator=(const MystringArray &str)
{
    delete []array;
    size= str.size;
    capacity= str.capacity;
    array= new Mystring[capacity];
    for(int i=0; i<size; i++)
    {
        array[i]=str.array[i];
    }
    return *this;
}

MystringArray &MystringArray::operator+=(const Mystring &str)
{
    if(size>=capacity)
    {
        capacity*=2;
        Mystring *newA= new Mystring[capacity];
        for(int i=0; i<size; i++)
        {
            newA[i]=array[i];
        }
        delete []array;
        array= newA;
    }
    array[size++]=str;
    return *this;
}

MystringArray &MystringArray::operator+=(const char c)
{
    Mystring str;
    if (size + 1 > capacity)
    {
        capacity *= 2;
        char *newS = new char[capacity];
        strcpy(newS, str.string);
        delete[] str.string;
        str.string = newS;
    }
    str.string[str.size++] = c;
    str.string[str.size] = '\0';
    array[size++] += str.string;
    return *this;
}

MystringArray MystringArray::operator+(const Mystring &str)
{
    MystringArray result = *this;
    result += str;
    return result;
}

MystringArray &MystringArray::operator-=(const Mystring &str)
{
    for(int i=0;i<size;i++)
    {
        if(strcmp(array[i].string,str.string) == 0)
        {
            for(int j=i;j<size;j++)
                array[j]= array[j+1];
            size--;
        }
    }
    return *this;
}

MystringArray MystringArray::operator-(const Mystring &str)
{
    MystringArray s= *this;
    s-=str;
    return s;
}

Mystring &MystringArray::operator[](int index)
{
    return array[index];
}

std::ostream &operator<<(std::ostream &os, const MystringArray &s)
{
    for(int i=0;i<s.size;i++)
        std::cout<< s.array[i]<<std::endl ;
    return os;
}

std::istream &operator>>(std::istream &is, MystringArray &s)
{
    Mystring str;
    char c = 0;
    while ((c = getchar()) != '\n')
    {
        str += c;
    }
    s.array[s.size]= str;
    s.size++;   
    return is;
}

MystringArray::~MystringArray()
{
    delete []array;
}

void MystringArray::show()
{
    for(int i=0; i<size; i++)
    {
        std::cout<<array[i]<<std::endl;
    }
}
